#pragma once
#include "Common.hpp"
#include "Loop.hpp"
#include "Acceptor.hpp"
#include "Channel.hpp"
#include "Connection.hpp"

class TcpServer{
private:    
    using ConnectedCallback = std::function<void(const PtrConnection&)>;
    using MessageCallback = std::function<void(const PtrConnection&, Buffer*)>;
    using ClosedCallback = std::function<void(const PtrConnection&)>;
    using AnyEventCallback = std::function<void(const PtrConnection&)>;
    using Functor = std::function<void()>;

    void RunAfterInLoop(const Functor& task, int delay){
        _next_id++;
        _baseloop.AddTimer(_next_id, delay, task);
    }

    // 为新连接构造一个 Connection 对象, 并管理起来
    void NewConnection(int fd){
         _next_id++;
        PtrConnection conn(new Connection(_pool.NextLoop(), _next_id, fd));
        conn->SetMessageCallback(_message_callback);
        conn->SetClosedCallback(_closed_callback);
        conn->SetConnectedCallback(_connected_callback);
        conn->SetAnyEventCallback(_event_callback);
        conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
        if (_enable_inactive_release) conn->EnableInactiveRelease(_timeout);//启动非活跃超时销毁
        
        conn->Established(); // 连接建立就绪, 启动读写事件监控, 调用连接建立成功的回调函数
        _conns.insert(std::make_pair(_next_id, conn));
    }

    void RemoveConnectionInLoop(const PtrConnection& conn){
        int id = conn->Id();
        auto it = _conns.find(id);
        if(it == _conns.end()) return ;
        _conns.erase(it); // 从管理的连接列表中移除连接信息
    }

    // 从管理的 Connection 对象中移除连接信息
    void RemoveConnection(const PtrConnection& conn){
        _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
    }


public:
    TcpServer(int port): 
        _port(port), 
        _next_id(0), 
        _timeout(0), 
        _enable_inactive_release(false), 
        _acceptor(&_baseloop, port),
        _pool(&_baseloop)
    {
        _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
        _acceptor.Listen();
    }

    // 1. 设置从属线程池数量
    void SetThreadCount(int cnt){_pool.SetThreadCount(cnt);}
    // 2. 设置各种回调函数
    void SetConnectedCallback(const ConnectedCallback& cb){_connected_callback = cb;}
    void SetMessageCallback(const MessageCallback& cb){_message_callback = cb;}
    void SetClosedCallback(const ConnectedCallback& cb){_closed_callback = cb;}
    void SetAnyEventCallback(const ConnectedCallback& cb){_event_callback = cb;}

    // 3. 是否启动非活跃连接超时销毁功能 
    void EnableInactiveRelease(int timeout){_enable_inactive_release = true; _timeout = timeout;}

    // 4. 添加定时功能 
    void RunAfter(const Functor& task, uint32_t delay){
        _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, task, delay));
    }

    // 5. 启动服务器
    void Start(){_pool.CreateThreads(); _baseloop.Start();}
private:
    uint64_t _next_id;      // 连接 ID 自增
    int _port;              // 监听端口
    int _timeout;           // 超时时间, 单位: 秒, 处理非活跃连接
    bool _enable_inactive_release; // 非活跃连接是否启动超时销毁功能的标志, 默认为 false
    EventLoop _baseloop;   // 主线程 EventLoop 对象, 负责监听事件处理
    Acceptor _acceptor;     // 监听套接字的管理对象
    LoopThreadPool _pool;   // 这是从属 EventLoop 线程池
    std::unordered_map<uint64_t, PtrConnection> _conns; // 管理所有连接对应的 shared_ptr 对象

    // 组件内的连接关闭回调 --- 组件内设置的
    ConnectedCallback _connected_callback; // 连接建立成功的回调函数
    MessageCallback _message_callback;     // 连接接收数据的回调函数
    ClosedCallback _closed_callback;    
    AnyEventCallback _event_callback;
    
};

class NetWork{
public:
    NetWork(){
        LOG_INFO("SIGPIPE is ignored");
        signal(SIGPIPE, SIG_IGN); // 忽略 SIGPIPE 信号, 防止程序崩溃
    }
};

static NetWork network; // 网络管理对象